﻿using ErrorOr;
using Gnivc.CarDealership.Api.Application.Abstractions.Repositories;
using Gnivc.CarDealership.Api.Domain.Entities;
using Gnivc.CarDealership.Api.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;

namespace Gnivc.CarDealership.Api.Infrastructure.Repositories;

public class PriceRepository : IPriceRepository
{
    private readonly IApplicationDbContext _context;

    public PriceRepository(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<ErrorOr<IEnumerable<Price>>> GetAllByVehicleAsync(Guid vehicleId)
    {
        return await _context.Prices
            .AsNoTracking()
            .Where(p => p.VehicleId == vehicleId)
            .OrderBy(p => p.StartDate)
            .ToListAsync();
    }
    public async Task<ErrorOr<Price>> GetCurrentPriceAsync(Guid vehicleId)
    {
        var price = await _context.Prices
            .AsNoTracking()
            .Where(p => p.VehicleId == vehicleId)
            .OrderByDescending(p => p.StartDate)
            .FirstOrDefaultAsync();

        if (price == null)
            return Error.NotFound();

        return price;
    }

    public async Task<ErrorOr<Created>> AddAsync(Price price)
    {
        await _context.Prices.AddAsync(price);
        var result = await _context.SaveChangesAsync();

        if (result < 1)
            return Error.Unexpected();

        return new Created();
    }

    public async Task<ErrorOr<Updated>> UpdateAsync(Price price)
    {
        _context.Prices.Update(price);
        var result = await _context.SaveChangesAsync();

        if (result < 1)
            return Error.Unexpected();

        return new Updated();
    }

    public async Task<ErrorOr<Deleted>> DeleteAsync(Guid priceId)
    {
        var price = await _context.Prices
            .Where(p => p.Id == priceId && !p.IsDeleted)
            .SingleOrDefaultAsync();

        if (price == null) 
            return Error.Unexpected();

        price.IsDeleted = true;

        var updateResult = await UpdateAsync(price);

        if (updateResult.IsError)
            return updateResult.Errors;

        return new Deleted();
    }


}
